﻿using System;
using System.Collections.Generic;
using System.Linq;
using HDM.NexusEngine.Core;
using HDM.NexusEngine.Input;
using HDM.NexusEngine.PathFinding;
using Tao.OpenGl;

namespace HDM.NexusEngine.Editor
{
    public class TestWalkState : IGameObject
    {
        private readonly InputManager _input;
        private readonly Scene _scene;
        private readonly Renderer _renderer = new Renderer();
        private bool _canWalkMousePosition;
        private List<Point> _path = new List<Point>();
        private readonly PathFinder _pathFinder = new PathFinder();
        private readonly PlayerCharacter _playerCharacter;
        private readonly Random _random = new Random();

        public TestWalkState(InputManager input, Scene scene, TextureManager textureManager)
        {
            _input = input;
            _scene = scene;
            _playerCharacter = new PlayerCharacter(textureManager);
        }

        public void Update(double elapsedTime)
        {
            _canWalkMousePosition = _scene.NavMesh.PolygonList.Any(x => x.Intersects(_input.Mouse.Position));
            if (_input.Mouse.LeftPressed && _canWalkMousePosition && _playerCharacter.FollowingPath == false)
            {
                _path = _pathFinder.GetPath(_playerCharacter.GetPosition(), _input.Mouse.Position, _scene.NavMesh);
                if (_path.Count >= 2)
                {
                    _playerCharacter.FollowPath(_path);
                }
            }

            _playerCharacter.Update(elapsedTime);
        }

        public void Render()
        {
            GLUtil.Clear(new Color(0, 0, 0, 1));
            Gl.glEnable(Gl.GL_TEXTURE_2D);

            foreach (var layer in _scene.Layers)
            {
                layer.Render(_renderer);
            }

            _renderer.Render();
            Gl.glDisable(Gl.GL_TEXTURE_2D);

            GLUtil.DrawFilledCircle(_input.Mouse.Position, 10,
                _canWalkMousePosition ? new Color(0, 1, 0, 1) : new Color(1, 0, 0, 1));

            // Draw the basic nav meshes
            GLUtil.SetColor(new Color(1, 0, 0, 1));
            _scene.NavMesh.PolygonList.ForEach(GLUtil.RenderPolygon);
            GLUtil.SetColor(new Color(1, 1, 1, 1));
            Gl.glLineWidth(4);
            Gl.glBegin(Gl.GL_LINE_STRIP);
            {
                foreach (var point in _path)
                {
                    GLUtil.DrawPointVertex(point);
                }
            }
            Gl.glEnd();
            Gl.glLineWidth(1);

            Gl.glEnable(Gl.GL_TEXTURE_2D);
            _playerCharacter.Render(_renderer);
            _renderer.Render();
            Gl.glDisable(Gl.GL_TEXTURE_2D);
        }

        public void Activated()
        {
            // Put the character in the center of a random polygon.
            var randomPoly = _scene.NavMesh.PolygonList[_random.Next(_scene.NavMesh.PolygonList.Count)];
            _playerCharacter.SetPosition(randomPoly.CalculateCentroid());
            _playerCharacter.FaceDown();
        }
    }
}